<?php

namespace app\yy\services;

use app\yy\model\Images as ImgModel;
use app\yy\model\Website as WebModel;
use think\Db;
use think\Exception;

class EasyShop extends BaseService
{

    public function yyToEasyShop($info, $dbstr, $category, $options, $products)
    {
        // 商品分类
        try {
            $category = $this->category($category, $dbstr);
        } catch (Exception $e) {
            WebModel::where('id', $info['id'])->update(['status' => 3, 'remark' => '商品分类迁移报错' . $e->getMessage(), 'end_time' => date('Y-m-d H:i:s')]);
            echo '商品分类迁移失败';
            die;
        }
        if (!$category) {
            WebModel::where('id', $info['id'])->update(['status' => 3, 'remark' => '商品分类迁移失败', 'end_time' => date('Y-m-d H:i:s')]);
            echo '商品分类迁移失败';
            die;
        }
        WebModel::where('id', $info['id'])->update(['remark' => '商品分类已迁移：' . date('Y-m-d H:i:s')]);
        $category = array_column($category, 'category_id', 'sku');

        // 选项
        try {
            [$db_option_name_list, $db_option_name_value] = $this->option($dbstr, $options);
        } catch (Exception $e) {
            WebModel::where('id', $info['id'])->update(['status' => 3, 'remark' => '商品选项迁移报错' . $e->getMessage(), 'end_time' => date('Y-m-d H:i:s')]);
            echo '商品分类迁移失败';
            die;
        }
        WebModel::where('id', $info['id'])->update(['remark' => '商品选项已迁移：' . date('Y-m-d H:i:s')]);

        // 商品信息
        try {
            $product = $this->createProducts($products, $dbstr, $category, $db_option_name_list, $db_option_name_value, $info);
        } catch (Exception $e) {
            WebModel::where('id', $info['id'])->update(['status' => 3, 'remark' => '商品迁移报错' . $e->getMessage(), 'end_time' => date('Y-m-d H:i:s')]);
            echo '商品迁移报错';
            die;
        }
        if (!$product) {
            WebModel::where('id', $info['id'])->update(['status' => 3, 'remark' => '商品迁移失败', 'end_time' => date('Y-m-d H:i:s')]);
            echo '商品迁移失败';
            die;
        }
        WebModel::where('id', $info['id'])->update(['status' => 4, 'image_status' => 0, 'remark' => '迁移成功', 'end_time' => date('Y-m-d H:i:s')]);
        echo '迁移成功';
        die;
    }

    /**
     * 新增商品
     * @param $list
     * @param $dbstr
     * @param $category
     * @param $db_option_name_list
     * @param $db_option_name_value
     * @param $find
     * @return bool
     * @throws Exception
     */
    public function createProducts($list, $dbstr, $category, $db_option_name_list, $db_option_name_value, $find): bool
    {
        // 清空商品数据
        Db::connect($dbstr)->table('product')->where('product_id', '>', 0)->delete();
        Db::connect($dbstr)->table('product_to_category')->where('product_id', '>=', 0)->delete();
        Db::connect($dbstr)->table('product_attribute')->where('product_id', '>=', 0)->delete();
        // 新增商品附图表
        Db::connect($dbstr)->execute("DROP TABLE IF EXISTS `product_to_images`;");
        Db::connect($dbstr)->execute("CREATE TABLE `product_to_images` (
              `product_id` int(11) NOT NULL,
              `image` varchar(255) NOT NULL COMMENT '图片附图'
            ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COMMENT='商品图片附图';");
        $productData = [];
        $toCategory = [];
        $toAttribute = [];
        $toImages = [];
        foreach ($list as $product) {
            $images = array_filter(explode(',', $product['images']));
            $image = $images[0] ?? '';
            $image = $this->oss_url . parse_url($image)['path'];
            $productData[] = [
                'sku' => $product['sku'],
                'name' => $product['name'],
                'short_description' => $product['short_description'],
                'description' => $product['description'],
                'meta_title' => $product['meta_title'],
                'meta_keywords' => $product['meta_keywords'],
                'meta_description' => $product['meta_description'],
                'status' => $product['status'],
                'carted' => $product['carted'],
                'master_category_id' => $category[$product['master_category']] ?? 0,
                'price' => $product['price'],
                'specials_price' => $product['specials_price'],
                'image' => $image,
                'date_added' => date('Y-m-d H:i:s')
            ];
        }

        // 添加到商品表
        if (!Db::connect($dbstr)->table('product')->limit(1000)->insertAll($productData)) {
            return false;
        }

        $product_list = Db::connect($dbstr)->table('product')->column('product_id', 'sku');
        foreach ($list as $goods) {
            $product_id = $product_list[$goods['sku']] ?? 0;
            if ($product_id) {
                // 附图
                $images = array_filter(explode(',', $goods['images']));
                foreach ($images as $img) {
                    $toImages[] = ['product_id' => $product_id, 'image' => $this->oss_url . parse_url($img)['path']];
                }

                // 分类
                foreach ($goods['master_categorys'] as $collection) {
                    if (isset($category[(string)$collection])) {
                        $toCategory[] = ['product_id' => $product_id, 'category_id' => $category[(string)$collection]];
                    }
                }
                // 选项
                $attribute = $this->attribute($dbstr, $product_id, $goods['options'], $goods['attribute'], $db_option_name_list, $db_option_name_value, $goods['specials_price']);
                $toAttribute = array_merge($toAttribute, $attribute);
            }
        }

        // 分类
        if ($toCategory) {
            Db::connect($dbstr)->table('product_to_category')->limit(1000)->insertAll($toCategory);
        }

        // 选项
        if ($toAttribute) {
            Db::connect($dbstr)->table('product_attribute')->limit(1000)->insertAll($toAttribute);
        }

        // 商品附图
        if ($toImages) {
            Db::connect($dbstr)->table('product_to_images')->limit(1000)->insertAll($toImages);
        }
        return true;
    }


    /**
     * 商品分类处理
     * @param $list
     * @param $dbstr
     * @return array
     * @throws Exception
     */
    public function category($list, $dbstr): array
    {
        try {
            $categoryList = $this->categoryFormat($list);
            $category_parent_list = [];
            $category = Db::connect($dbstr)->table('category')->column('category_id', 'sku');
            foreach ($categoryList as $key => $item) {
                $parent_id = 0;
                $parent_sku = $item['name'];
                if ($item['parent_sku']) {
                    $parent_sku = $item['parent_sku'] . '/' . $item['name'];
                    $parent_id = $category_parent_list[$item['parent_sku']] ?? 0;
                }
                $insert = [
                    'name' => $item['name'],
                    'sku' => $item['title'],
                    'parent_id' => $parent_id,
                    'meta_title' => $item['name'],
                    'meta_keywords' => $item['name'],
                    'meta_description' => $item['name'],
                    'sort_order' => $key,
                    'date_added' => date('Y-m-d H:i:s')
                ];
                $category_id = $category[$item['title']] ?? 0;
                if ($category_id) {
                    Db::connect($dbstr)->table('category')->where('sku', $item['title'])->update($insert);
                } else {
                    $category_id = Db::connect($dbstr)->table('category')->insertGetId($insert);
                }
                $category_parent_list[$parent_sku] = $category_id;
            }
            return Db::connect($dbstr)->table('category')->select();
        } catch (Exception $e) {
            return [];
        }
    }


    /**
     * 选项值
     * @param $dbstr
     * @param $options
     * @return array
     * @throws Exception
     */
    public function option($dbstr, $options): array
    {
        $db_option_name_list = Db::connect($dbstr)->table('product_option')->column('product_option_id', 'name');
        $db_option_name_value = [];
        foreach ($db_option_name_list as $db_option_name => $db_option_id) {
            $db_option_name_value[$db_option_name] = Db::connect($dbstr)->table('product_option_value')->where('product_option_id', $db_option_id)->column('product_option_value_id', 'name');
        }
        $i = 1;
        foreach ($options as $option_name => $option_values) {
            $product_option_id = $db_option_name_list[(string)$option_name] ?? 0;
            if (!$product_option_id) {
                $product_option_id = Db::connect($dbstr)->table('product_option')->insertGetId(['name' => (string)$option_name, 'sort_order' => $i]);
                $db_option_name_list[(string)$option_name] = $product_option_id;
            }
            foreach ($option_values as $value_sort => $op_name_value) {
                $product_option_value_id = $db_option_name_value[(string)$option_name][(string)$op_name_value] ?? 0;
                if (!$product_option_value_id) {
                    $product_option_value_id = Db::connect($dbstr)->table('product_option_value')->insertGetId(['name' => (string)$op_name_value, 'sort_order' => $value_sort, 'product_option_id' => $product_option_id]);
                    $db_option_name_value[(string)$option_name][(string)$op_name_value] = $product_option_value_id;
                }
            }
            $i++;
        }
        return [$db_option_name_list, $db_option_name_value];
    }

    /**
     * 商品属性值
     * @param $dbstr
     * @param $product_id
     * @param $variants
     * @param $attribute
     * @param $db_option_name_list
     * @param $db_option_name_value
     * @param $price
     * @return array
     */
    public function attribute($dbstr, $product_id, $variants, $attribute, $db_option_name_list, $db_option_name_value, $price): array
    {
        $option_price = [];
        if ($attribute) {
            $option_price = $this->getOptionPrice($attribute, $price);
        }
        $data = [];
        foreach ($variants as $var) {
            $product_option_id = $db_option_name_list[(string)$var['option_name']] ?? 0;
            $var_option_value = array_unique($var['option_value']);
            foreach ($var_option_value as $option_value) {
                $product_option_value_id = $db_option_name_value[(string)$var['option_name']][(string)$option_value] ?? 0;
                if ($product_option_id && $product_option_value_id) {
                    $add_price = $option_price[$option_value] ?? 0;
                    $price_prefix = '+';
                    if ($add_price < 0) {
                        $price_prefix = '-';
                    }
                    $data[] = [
                        'product_id' => $product_id,
                        'product_option_id' => $product_option_id,
                        'product_option_value_id' => $product_option_value_id,
                        'price' => abs($add_price),
                        'price_prefix' => $price_prefix
                    ];
                }
            }
        }
        return $data;
    }

    public function preload_image($info,$dbStr,$bool){
        $where = [
            'website_id' => $info['id'],
            'rank' => '0',
        ];
        try {
            if ($bool) {
                // 获取首页图片
                $bestsellers = Db::connect($dbStr)->table('product')->where(['status' => 1, 'in_stock' => 1])->field('sku,product_id,name,image,price,specials_price,specials_expire_date')->order('ordered DESC, sort_order ASC')->limit(40)->select();
                $featured = Db::connect($dbStr)->table('product')->where(['status' => 1, 'in_stock' => 1])->field('sku,product_id,name,image,price,specials_price,specials_expire_date')->order('viewed DESC, sort_order ASC')->limit(40)->select();
                $new_products = Db::connect($dbStr)->table('product')->where(['status' => 1, 'in_stock' => 1])->field('sku,product_id,name,image,price,specials_price,specials_expire_date')->order('date_added DESC, sort_order ASC')->limit(40)->select();
                $specials = Db::connect($dbStr)->table('product')->where(['status' => 1, 'in_stock' => 1])->where('specials_price', '>', 0)->field('sku,product_id,name,image,price,specials_price,specials_expire_date')->order('specials_price, sort_order')->limit(40)->select();
                $bestsellers = array_column($bestsellers, 'sku');
                $featured = array_column($featured, 'sku');
                $new_products = array_column($new_products, 'sku');
                $specials = array_column($specials, 'sku');
                // 尺寸
                $size = Db::connect($dbStr)->table('configuration')->where('configuration_key', 'in', [
                    'BESTSELLERS_IMAGE_WIDTH', 'BESTSELLERS_IMAGE_HEIGHT',
                    'FEATURED_IMAGE_WIDTH', 'FEATURED_IMAGE_HEIGHT',
                    'NEW_PRODUCTS_IMAGE_WIDTH', 'NEW_PRODUCTS_IMAGE_HEIGHT',
                    'SPECIALS_IMAGE_WIDTH', 'SPECIALS_IMAGE_HEIGHT'
                ])->column('configuration_value', 'configuration_key');
                $bestsellers_list = ImgModel::where($where)->where('image_status', 0)->where('sku', 'in', $bestsellers)->field("id,yy_image,oss_image")->select()->toArray();
                $featured_list = ImgModel::where($where)->where('image_status', 0)->where('sku', 'in', $featured)->field("id,yy_image,oss_image")->select()->toArray();
                $new_products_list = ImgModel::where($where)->where('image_status', 0)->where('sku', 'in', $new_products)->field("id,yy_image,oss_image")->select()->toArray();
                $specials_list = ImgModel::where($where)->where('image_status', 0)->where('sku', 'in', $specials)->field("id,yy_image,oss_image")->select()->toArray();
                $bestsellers_size = ['width' => $size['BESTSELLERS_IMAGE_WIDTH'], 'height' => $size['BESTSELLERS_IMAGE_HEIGHT']];
                $this->longRange($bestsellers_list, $info, [$bestsellers_size], $bool);
                $featured_size = ['width' => $size['FEATURED_IMAGE_WIDTH'], 'height' => $size['FEATURED_IMAGE_HEIGHT']];
                $this->longRange($featured_list, $info, [$featured_size], $bool);
                $new_products_size = ['width' => $size['NEW_PRODUCTS_IMAGE_WIDTH'], 'height' => $size['NEW_PRODUCTS_IMAGE_HEIGHT']];
                $this->longRange($new_products_list, $info, [$new_products_size], $bool);
                $specials_size = ['width' => $size['SPECIALS_IMAGE_WIDTH'], 'height' => $size['SPECIALS_IMAGE_HEIGHT']];
                $this->longRange($specials_list, $info, [$specials_size], $bool);
            } else {

                // 获取网站分类页主图
                $image_list = ImgModel::where($where)->where('image_status', 0)->field("id,yy_image,oss_image")->order('id')->limit(1000)->select()->toArray();
                if (!$image_list) {
                    WebModel::where('id', $info['id'])->update(['image_status' => 4, 'image_end' => date('Y-m-d H:i:s')]);
                    // 清除数据缓存
                    $option = array('ssl' => array('verify_peer' => false, 'verify_peer_name' => false));
                    file_get_contents("https://{$info['domain']}/{$this->web_url}?token=y1goj8Pbr3VzPdS&active=clearSql", false, stream_context_create($option));
                }

                // 图片迁移中
                $image_ids = array_column($image_list, 'id');
                ImgModel::where('id', 'in', $image_ids)->update(['image_status' => 2, 'image_start' => date('Y-m-d H:i:s')]);

                $size = Db::connect($dbStr)->table('configuration')->where('configuration_key', 'in', [
                    'MOBILE_GRID_IMAGE_WIDTH', 'MOBILE_GRID_IMAGE_HEIGHT',
                    'MOBILE_LIST_IMAGE_WIDTH', 'MOBILE_LIST_IMAGE_HEIGHT',
                    'GRID_IMAGE_WIDTH', 'GRID_IMAGE_HEIGHT',
                    'LIST_IMAGE_WIDTH', 'LIST_IMAGE_HEIGHT',
                ])->column('configuration_value', 'configuration_key');
                $category_size = [
                    ['width' => $size['MOBILE_GRID_IMAGE_WIDTH'], 'height' => $size['MOBILE_GRID_IMAGE_HEIGHT']],
                    ['width' => $size['MOBILE_LIST_IMAGE_WIDTH'], 'height' => $size['MOBILE_LIST_IMAGE_HEIGHT']],
                    ['width' => $size['GRID_IMAGE_WIDTH'], 'height' => $size['GRID_IMAGE_HEIGHT']],
                    ['width' => $size['LIST_IMAGE_WIDTH'], 'height' => $size['LIST_IMAGE_HEIGHT']],
                ];
                $this->longRange($image_list, $info, $category_size);
            }
        } catch (Exception $e) {
            WebModel::where('id', $info['id'])->update(['image_status' => 4, 'image_end' => date('Y-m-d H:i:s')]);
        }
        return true;
    }

    /**
     * @param $image_list
     * @param $info
     * @param $size
     * @param bool $bool
     * @return true
     */
    public function longRange($image_list, $info, $size, $bool = false): bool
    {
        $url = "https://{$info['domain']}/{$this->web_url}";
        $img_arr = array_chunk($image_list, 100);
        foreach ($img_arr as $arr) {
            $list = ['size' => $size, 'list' => $arr];
            $data = postUrl($url, ['token' => 'y1goj8Pbr3VzPdS', 'data' => json_encode($list)]);
            if (!$bool) {
                $arrIds = array_column($arr, 'id');
                if (isset($data['code'])) {
                    ImgModel::where('id', 'in', $arrIds)->update(['image_status' => 1, 'remark' => '缩略图成功', 'image_end' => date('Y-m-d H:i:s')]);
                } else {
                    ImgModel::where('id', 'in', $arrIds)->update(['image_status' => 3, 'image_end' => date('Y-m-d H:i:s')]);
                }
            }
        }
        return true;
    }

}